/*
 * Copyright (C) 2013 Buptcoder
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.buptcoder.wifimap;

import java.util.Locale;

import com.buptcoder.wifimap.Utils.Constants;
import com.buptcoder.wifimap.Utils.MapLog;
import com.buptcoder.wifimap.Utils.Utils;
import com.buptcoder.wifimap.location.Locator;

import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;

import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class WifiAPListActivity extends ListActivity implements
        View.OnClickListener, Locator.OnLocationChangedListener,
        AdapterView.OnItemClickListener {
    private static final String TAG = "MainActivity";
    private Locator mLocator;
    private ContentResolver mContentResolver;
    private APInfoListAdapter mAdapter;
    private Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.activity_main_layout);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
                R.layout.custom_titlebar);
        mContext = this;
        setTitle();
        setButtons();
        confirmGPS();

        mLocator = Locator.getInstance(this.getApplicationContext());
        mLocator.addLocationChangeListener(this);

        mContentResolver = this.getContentResolver();

        mAdapter = new APInfoListAdapter(this, null);
        getListView().setOnItemClickListener(this);
        setListAdapter(mAdapter);
        refreshWifi();

    }

    @Override
    protected void onDestroy() {
        if (mLocator != null) {
            mLocator = null;
        }
        super.onDestroy();
    }

    private void setTitle() {
        TextView titleView = (TextView) findViewById(R.id.titlebar_title);
        titleView.setText(R.string.app_name);

    }

    private void setButtons() {
        ImageView mapImage = (ImageView) findViewById(R.id.map_button);
        mapImage.setOnClickListener(this);

        Button refreshButton = (Button) findViewById(R.id.wifi_refresh);
        refreshButton.setOnClickListener(this);
    }

    private void confirmGPS() {
        boolean gpsEnabled = Settings.Secure.isLocationProviderEnabled(
                getContentResolver(), LocationManager.GPS_PROVIDER);
        MapLog.d(TAG, "GPS status: " + gpsEnabled);
        if (!gpsEnabled) {
            showOpenGPSDialog();
        }
    }

    private void showOpenGPSDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle(R.string.string_open_gps_title).setMessage(
                R.string.string_open_gps_content);
        builder.setPositiveButton(R.string.string_open_gps_settings,
                new AlertDialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(
                                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        mContext.startActivity(intent);
                    }
                });
        builder.setNegativeButton(android.R.string.cancel, null);
        builder.create().show();
    }

    private void updateWithNewLocation() {
        String latLongString;
        if (mLocator != null) {
            double lat = mLocator.getLatitude();
            double lng = mLocator.getLongitude();
            latLongString = "Latitude: " + lat + "\n Logitude: " + lng;
        } else {
            latLongString = "Cannot get the position.";
        }
        MapLog.d(TAG, latLongString);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.map_button) {
            showMapActivity();
        } else if (id == R.id.wifi_refresh) {
            refreshWifi();
        }
    }

    private void showMapActivity() {
        Intent intent = new Intent(this, AllAPMapActivity.class);
        this.startActivity(intent);
    }

    private void refreshWifi() {
        LoadDataTask task = new LoadDataTask();
        task.execute();
    }

    @Override
    public void onLocationChanged() {
        updateWithNewLocation();
    }

    private void setEmptyText() {
        TextView emptyView = (TextView) findViewById(R.id.emptyText);
        if (getListAdapter().getCount() > 0) {
            emptyView.setVisibility(View.GONE);
        } else {
            emptyView.setVisibility(View.VISIBLE);
            emptyView
                    .sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view,
            int position, long id) {
        if (mAdapter != null) {
            Cursor cursor = (Cursor) mAdapter.getItem(position);
            double lat = cursor.getDouble(Constants.PROJECT_INDEX.LAT
                    .getIndex());
            double lon = cursor.getDouble(Constants.PROJECT_INDEX.LON
                    .getIndex());
            if (lat == 0 || lon == 0) {
                Toast.makeText(this, R.string.string_no_location_info,
                        Toast.LENGTH_SHORT).show();
                return;
            }
            String ssid = cursor.getString(Constants.PROJECT_INDEX.SSID
                    .getIndex());
            int type = cursor.getInt(Constants.PROJECT_INDEX.TYPE.getIndex());

            Intent intent = new Intent(this, SingleAPMapActivity.class);
            intent.putExtra(Constants.APINFO_LAT_KEY, lat);
            intent.putExtra(Constants.APINFO_LON_KEY, lon);
            intent.putExtra(Constants.APINFO_SSID_KEY, ssid);
            intent.putExtra(Constants.APINFO_TYPE_KEY, type);
            startActivity(intent);
        }
    }

    protected static final class ViewHolder {
        private TextView mSSIDView;
        private TextView mDistanceView;
        /** The widget displays icon. */
        private ImageView mIconView;

        /** Constructor. */
        protected ViewHolder() {
        }
    }

    class APInfoListAdapter extends CursorAdapter {
        private Context mContext;

        @SuppressWarnings("deprecation")
        public APInfoListAdapter(Context context, Cursor c) {
            super(context, c);
            mContext = context;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            ViewHolder holder = (ViewHolder) view.getTag();
            String ssid = cursor.getString(Constants.PROJECT_INDEX.SSID
                    .getIndex());
            int type = cursor.getInt(Constants.PROJECT_INDEX.TYPE.getIndex());
            if (type == 0) {
                holder.mIconView.setImageResource(R.drawable.unlock);
            } else {
                holder.mIconView.setImageResource(R.drawable.lock);
            }

            double lat = cursor.getDouble(Constants.PROJECT_INDEX.LAT
                    .getIndex());
            double lon = cursor.getDouble(Constants.PROJECT_INDEX.LON
                    .getIndex());
            if (lat != 0 && lon != 0) {
                double distance = Utils.getDistance(lat, lon,
                        mLocator.getLatitude(), mLocator.getLongitude());
                String dis = String.format(Locale.getDefault(), "%.2f",
                        distance);
                if (Float.valueOf(dis) == 0) {
                    dis = "0";
                }
                String distanceString = getString(R.string.string_distance, dis);
                holder.mDistanceView.setText(distanceString);
            } else {
                holder.mDistanceView.setText(R.string.string_distance_unknown);
            }
            holder.mSSIDView.setText(ssid);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View itemView = inflater.inflate(R.layout.access_point_item, null);
            ViewHolder cache = new ViewHolder();
            cache.mSSIDView = (TextView) itemView.findViewById(R.id.ssid_name);
            cache.mIconView = (ImageView) itemView
                    .findViewById(R.id.head_image);
            cache.mDistanceView = (TextView) itemView
                    .findViewById(R.id.discance);
            itemView.setTag(cache);
            return itemView;
        }

        @Override
        public void changeCursor(final Cursor aCursor) {
        }
    }

    class LoadDataTask extends AsyncTask<Void, Void, Cursor> {
        @Override
        protected Cursor doInBackground(Void... params) {
            try {
                return mContentResolver.query(Constants.WIFI_APINFO_URL,
                        Constants.getWifiProjection(), null, null, null);
            } catch (SQLiteException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Cursor aCursor) {
            if (aCursor != null) {
                MapLog.d(TAG, "aCursor size: " + aCursor.getCount());
                if (Build.VERSION.SDK_INT >= 11) {
                    mAdapter.swapCursor(aCursor);
                } else {
                    mAdapter = new APInfoListAdapter(WifiAPListActivity.this,
                            aCursor);
                    setListAdapter(mAdapter);
                }
                mAdapter.notifyDataSetChanged();
                setEmptyText();
            }
        }
    }

}
